﻿package org.flixel
{
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;
    import flash.ui.*;
    import flash.utils.*;
    import org.flixel.plugin.*;
    import org.flixel.system.*;

    public class FlxGame extends Sprite
    {
        protected var junk:String = "FlxGame_junk";
        protected var SndBeep:Class;
        protected var ImgLogo:Class;
        public var useSoundHotKeys:Boolean;
        public var useSystemCursor:Boolean;
        public var forceDebugger:Boolean;
        var _state:FlxState;
        var _mouse:Sprite;
        protected var _iState:Class;
        protected var _created:Boolean;
        protected var _total:uint;
        protected var _accumulator:int;
        protected var _lostFocus:Boolean;
        var _step:uint;
        var _flashFramerate:uint;
        var _maxAccumulation:uint;
        var _requestedState:FlxState;
        var _requestedReset:Boolean;
        protected var _focus:Sprite;
        protected var _soundTray:Sprite;
        protected var _soundTrayTimer:Number;
        protected var _soundTrayBars:Array;
        var _debugger:FlxDebugger;
        var _debuggerUp:Boolean;
        var _replay:FlxReplay;
        var _replayRequested:Boolean;
        var _recordingRequested:Boolean;
        var _replaying:Boolean;
        var _recording:Boolean;
        var _replayCancelKeys:Array;
        var _replayTimer:int;
        var _replayCallback:Function;

        public function FlxGame(param1:uint, param2:uint, param3:Class, param4:Number = 1, param5:uint = 60, param6:uint = 30, param7:Boolean = false)
        {
            this.SndBeep = FlxGame_SndBeep;
            this.ImgLogo = FlxGame_ImgLogo;
            this._lostFocus = false;
            this._focus = new Sprite();
            this._focus.visible = false;
            this._soundTray = new Sprite();
            this._mouse = new Sprite();
            FlxG.init(this, param1, param2, param4);
            FlxG.framerate = param5;
            FlxG.flashFramerate = param6;
            this._accumulator = this._step;
            this._total = 0;
            this._state = null;
            this.useSoundHotKeys = true;
            this.useSystemCursor = param7;
            if (!this.useSystemCursor)
            {
                Mouse.hide();
            }
            this.forceDebugger = false;
            this._debuggerUp = false;
            this._replay = new FlxReplay();
            this._replayRequested = false;
            this._recordingRequested = false;
            this._replaying = false;
            this._recording = false;
            this._iState = param3;
            this._requestedState = null;
            this._requestedReset = true;
            this._created = false;
            addEventListener(Event.ENTER_FRAME, this.create);
            return;
        }// end function

        function showSoundTray(param1:Boolean = false) : void
        {
            if (!param1)
            {
                FlxG.play(this.SndBeep);
            }
            this._soundTrayTimer = 1;
            this._soundTray.y = 0;
            this._soundTray.visible = true;
            var _loc_2:* = Math.round(FlxG.volume * 10);
            if (FlxG.mute)
            {
                _loc_2 = 0;
            }
            var _loc_3:uint = 0;
            while (_loc_3 < this._soundTrayBars.length)
            {
                
                if (_loc_3 < _loc_2)
                {
                    this._soundTrayBars[_loc_3].alpha = 1;
                }
                else
                {
                    this._soundTrayBars[_loc_3].alpha = 0.5;
                }
                _loc_3 = _loc_3 + 1;
            }
            return;
        }// end function

        protected function onKeyUp(event:KeyboardEvent) : void
        {
            var _loc_2:int = 0;
            var _loc_3:String = null;
            if (this._debuggerUp && this._debugger.watch.editing)
            {
                return;
            }
            if (!FlxG.mobile)
            {
                if (this._debugger != null && (event.keyCode == 192 || event.keyCode == 220))
                {
                    this._debugger.visible = !this._debugger.visible;
                    this._debuggerUp = this._debugger.visible;
                    if (this._debugger.visible)
                    {
                        Mouse.show();
                    }
                    else if (!this.useSystemCursor)
                    {
                        Mouse.hide();
                    }
                    return;
                }
                if (this.useSoundHotKeys)
                {
                    _loc_2 = event.keyCode;
                    _loc_3 = String.fromCharCode(event.charCode);
                    switch(_loc_2)
                    {
                        case 48:
                        case 96:
                        {
                            FlxG.mute = !FlxG.mute;
                            if (FlxG.volumeHandler != null)
                            {
                                FlxG.volumeHandler(FlxG.mute ? (0) : (FlxG.volume));
                            }
                            this.showSoundTray();
                            return;
                        }
                        case 109:
                        case 189:
                        {
                            FlxG.mute = false;
                            FlxG.volume = FlxG.volume - 0.1;
                            this.showSoundTray();
                            return;
                        }
                        case 107:
                        case 187:
                        {
                            FlxG.mute = false;
                            FlxG.volume = FlxG.volume + 0.1;
                            this.showSoundTray();
                            return;
                        }
                        default:
                        {
                            break;
                            break;
                        }
                    }
                }
            }
            if (this._replaying)
            {
                return;
            }
            FlxG.keys.handleKeyUp(event);
            return;
        }// end function

        protected function onKeyDown(event:KeyboardEvent) : void
        {
            var _loc_2:Boolean = false;
            var _loc_3:String = null;
            var _loc_4:uint = 0;
            var _loc_5:uint = 0;
            if (this._debuggerUp && this._debugger.watch.editing)
            {
                return;
            }
            if (this._replaying && this._replayCancelKeys != null && this._debugger == null && event.keyCode != 192 && event.keyCode != 220)
            {
                _loc_2 = false;
                _loc_4 = 0;
                _loc_5 = this._replayCancelKeys.length;
                while (_loc_4 < _loc_5)
                {
                    
                    _loc_3 = this._replayCancelKeys[_loc_4++];
                    if (_loc_3 == "ANY" || FlxG.keys.getKeyCode(_loc_3) == event.keyCode)
                    {
                        if (this._replayCallback != null)
                        {
                            this._replayCallback();
                            this._replayCallback = null;
                        }
                        else
                        {
                            FlxG.stopReplay();
                        }
                        break;
                    }
                }
                return;
            }
            FlxG.keys.handleKeyDown(event);
            return;
        }// end function

        protected function onMouseDown(event:MouseEvent) : void
        {
            var _loc_2:String = null;
            var _loc_3:uint = 0;
            var _loc_4:uint = 0;
            if (this._debuggerUp)
            {
                if (this._debugger.hasMouse)
                {
                    return;
                }
                if (this._debugger.watch.editing)
                {
                    this._debugger.watch.submit();
                }
            }
            if (this._replaying && this._replayCancelKeys != null)
            {
                _loc_3 = 0;
                _loc_4 = this._replayCancelKeys.length;
                while (_loc_3 < _loc_4)
                {
                    
                    _loc_2 = this._replayCancelKeys[_loc_3++] as String;
                    if (_loc_2 == "MOUSE" || _loc_2 == "ANY")
                    {
                        if (this._replayCallback != null)
                        {
                            this._replayCallback();
                            this._replayCallback = null;
                        }
                        else
                        {
                            FlxG.stopReplay();
                        }
                        break;
                    }
                }
                return;
            }
            FlxG.mouse.handleMouseDown(event);
            return;
        }// end function

        protected function onMouseUp(event:MouseEvent) : void
        {
            if (this._debuggerUp && this._debugger.hasMouse || this._replaying)
            {
                return;
            }
            FlxG.mouse.handleMouseUp(event);
            return;
        }// end function

        protected function onMouseWheel(event:MouseEvent) : void
        {
            if (this._debuggerUp && this._debugger.hasMouse || this._replaying)
            {
                return;
            }
            FlxG.mouse.handleMouseWheel(event);
            return;
        }// end function

        protected function onFocus(event:Event = null) : void
        {
            if (!this._debuggerUp && !this.useSystemCursor)
            {
                Mouse.hide();
            }
            FlxG.resetInput();
            var _loc_2:Boolean = false;
            this._focus.visible = false;
            this._lostFocus = _loc_2;
            stage.frameRate = this._flashFramerate;
            FlxG.resumeSounds();
            return;
        }// end function

        protected function onFocusLost(event:Event = null) : void
        {
            if (x != 0 || y != 0)
            {
                x = 0;
                y = 0;
            }
            Mouse.show();
            var _loc_2:Boolean = true;
            this._focus.visible = true;
            this._lostFocus = _loc_2;
            stage.frameRate = 10;
            FlxG.pauseSounds();
            return;
        }// end function

        protected function onEnterFrame(event:Event = null) : void
        {
            var _loc_2:* = getTimer();
            var _loc_3:* = _loc_2 - this._total;
            this._total = _loc_2;
            this.updateSoundTray(_loc_3);
            if (!this._lostFocus)
            {
                if (this._debugger != null && this._debugger.vcr.paused)
                {
                    if (this._debugger.vcr.stepRequested)
                    {
                        this._debugger.vcr.stepRequested = false;
                        this.step();
                    }
                }
                else
                {
                    this._accumulator = this._accumulator + _loc_3;
                    if (this._accumulator > this._maxAccumulation)
                    {
                        this._accumulator = this._maxAccumulation;
                    }
                    while (this._accumulator >= this._step)
                    {
                        
                        this.step();
                        this._accumulator = this._accumulator - this._step;
                    }
                }
                FlxBasic._VISIBLECOUNT = 0;
                this.draw();
                if (this._debuggerUp)
                {
                    this._debugger.perf.flash(_loc_3);
                    this._debugger.perf.visibleObjects(FlxBasic._VISIBLECOUNT);
                    this._debugger.perf.update();
                    this._debugger.watch.update();
                }
            }
            return;
        }// end function

        protected function switchState() : void
        {
            FlxG.resetCameras();
            FlxG.resetInput();
            FlxG.destroySounds();
            FlxG.clearBitmapCache();
            if (this._debugger != null)
            {
                this._debugger.watch.removeAll();
            }
            var _loc_1:* = FlxTimer.manager;
            if (_loc_1 != null)
            {
                _loc_1.clear();
            }
            if (this._state != null)
            {
                this._state.destroy();
            }
            this._state = this._requestedState;
            this._state.create();
            return;
        }// end function

        protected function step() : void
        {
            if (this._requestedReset)
            {
                this._requestedReset = false;
                this._requestedState = new this._iState();
                this._replayTimer = 0;
                this._replayCancelKeys = null;
                FlxG.reset();
            }
            if (this._recordingRequested)
            {
                this._recordingRequested = false;
                this._replay.create(FlxG.globalSeed);
                this._recording = true;
                if (this._debugger != null)
                {
                    this._debugger.vcr.recording();
                    FlxG.log("FLIXEL: starting new flixel gameplay record.");
                }
            }
            else if (this._replayRequested)
            {
                this._replayRequested = false;
                this._replay.rewind();
                FlxG.globalSeed = this._replay.seed;
                if (this._debugger != null)
                {
                    this._debugger.vcr.playing();
                }
                this._replaying = true;
            }
            if (this._state != this._requestedState)
            {
                this.switchState();
            }
            FlxBasic._ACTIVECOUNT = 0;
            if (this._replaying)
            {
                this._replay.playNextFrame();
                if (this._replayTimer > 0)
                {
                    this._replayTimer = this._replayTimer - this._step;
                    if (this._replayTimer <= 0)
                    {
                        if (this._replayCallback != null)
                        {
                            this._replayCallback();
                            this._replayCallback = null;
                        }
                        else
                        {
                            FlxG.stopReplay();
                        }
                    }
                }
                if (this._replaying && this._replay.finished)
                {
                    FlxG.stopReplay();
                    if (this._replayCallback != null)
                    {
                        this._replayCallback();
                        this._replayCallback = null;
                    }
                }
                if (this._debugger != null)
                {
                    this._debugger.vcr.updateRuntime(this._step);
                }
            }
            else
            {
                FlxG.updateInput();
            }
            if (this._recording)
            {
                this._replay.recordFrame();
                if (this._debugger != null)
                {
                    this._debugger.vcr.updateRuntime(this._step);
                }
            }
            this.update();
            FlxG.mouse.wheel = 0;
            if (this._debuggerUp)
            {
                this._debugger.perf.activeObjects(FlxBasic._ACTIVECOUNT);
            }
            return;
        }// end function

        protected function updateSoundTray(param1:Number) : void
        {
            var _loc_2:FlxSave = null;
            if (this._soundTray != null)
            {
                if (this._soundTrayTimer > 0)
                {
                    this._soundTrayTimer = this._soundTrayTimer - param1 / 1000;
                }
                else if (this._soundTray.y > -this._soundTray.height)
                {
                    this._soundTray.y = this._soundTray.y - param1 / 1000 * FlxG.height * 2;
                    if (this._soundTray.y <= -this._soundTray.height)
                    {
                        this._soundTray.visible = false;
                        _loc_2 = new FlxSave();
                        if (_loc_2.bind("flixel"))
                        {
                            if (_loc_2.data.sound == null)
                            {
                                _loc_2.data.sound = new Object();
                            }
                            _loc_2.data.sound.mute = FlxG.mute;
                            _loc_2.data.sound.volume = FlxG.volume;
                            _loc_2.close();
                        }
                    }
                }
            }
            return;
        }// end function

        protected function update() : void
        {
            var _loc_1:* = getTimer();
            FlxG.elapsed = FlxG.timeScale * (this._step / 1000);
            FlxG.updateSounds();
            FlxG.updatePlugins();
            this._state.update();
            FlxG.updateCameras();
            if (this._debuggerUp)
            {
                this._debugger.perf.flixelUpdate(getTimer() - _loc_1);
            }
            return;
        }// end function

        protected function draw() : void
        {
            var _loc_1:* = getTimer();
            FlxG.lockCameras();
            this._state.draw();
            FlxG.drawPlugins();
            FlxG.unlockCameras();
            if (this._debuggerUp)
            {
                this._debugger.perf.flixelDraw(getTimer() - _loc_1);
            }
            return;
        }// end function

        protected function create(event:Event) : void
        {
            if (root == null)
            {
                return;
            }
            removeEventListener(Event.ENTER_FRAME, this.create);
            this._total = getTimer();
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.frameRate = this._flashFramerate;
            stage.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
            stage.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
            stage.addEventListener(MouseEvent.MOUSE_WHEEL, this.onMouseWheel);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, this.onKeyDown);
            stage.addEventListener(KeyboardEvent.KEY_UP, this.onKeyUp);
            addChild(this._mouse);
            if (!FlxG.mobile)
            {
                if (FlxG.debug || this.forceDebugger)
                {
                    this._debugger = new FlxDebugger(FlxG.width * FlxCamera.defaultZoom, FlxG.height * FlxCamera.defaultZoom);
                    addChild(this._debugger);
                }
                this.createSoundTray();
                stage.addEventListener(Event.DEACTIVATE, this.onFocusLost);
                stage.addEventListener(Event.ACTIVATE, this.onFocus);
                this.createFocusScreen();
            }
            addEventListener(Event.ENTER_FRAME, this.onEnterFrame);
            return;
        }// end function

        protected function createSoundTray() : void
        {
            this._soundTray.visible = false;
            this._soundTray.scaleX = 2;
            this._soundTray.scaleY = 2;
            var _loc_1:* = new Bitmap(new BitmapData(80, 30, true, 2130706432));
            this._soundTray.x = FlxG.width / 2 * FlxCamera.defaultZoom - _loc_1.width / 2 * this._soundTray.scaleX;
            this._soundTray.addChild(_loc_1);
            var _loc_2:* = new TextField();
            _loc_2.width = _loc_1.width;
            _loc_2.height = _loc_1.height;
            _loc_2.multiline = true;
            _loc_2.wordWrap = true;
            _loc_2.selectable = false;
            _loc_2.embedFonts = true;
            _loc_2.antiAliasType = AntiAliasType.NORMAL;
            _loc_2.gridFitType = GridFitType.PIXEL;
            _loc_2.defaultTextFormat = new TextFormat("system", 8, 16777215, null, null, null, null, null, "center");
            this._soundTray.addChild(_loc_2);
            _loc_2.text = "VOLUME";
            _loc_2.y = 16;
            var _loc_3:uint = 10;
            var _loc_4:uint = 14;
            this._soundTrayBars = new Array();
            var _loc_5:uint = 0;
            while (++_loc_5 < 10)
            {
                
                _loc_1 = new Bitmap(new BitmapData(4, ++_loc_5, false, 16777215));
                _loc_1.x = _loc_3;
                _loc_1.y = _loc_4;
                this._soundTrayBars.push(this._soundTray.addChild(_loc_1));
                _loc_3 = _loc_3 + 6;
                _loc_4 = _loc_4 - 1;
            }
            this._soundTray.y = -this._soundTray.height;
            this._soundTray.visible = false;
            addChild(this._soundTray);
            var _loc_6:* = new FlxSave();
            if (new FlxSave().bind("flixel") && _loc_6.data.sound != null)
            {
                if (_loc_6.data.sound.volume != null)
                {
                    FlxG.volume = _loc_6.data.sound.volume;
                }
                if (_loc_6.data.sound.mute != null)
                {
                    FlxG.mute = _loc_6.data.sound.mute;
                }
                _loc_6.destroy();
            }
            return;
        }// end function

        protected function createFocusScreen() : void
        {
            var _loc_1:* = this._focus.graphics;
            var _loc_2:* = FlxG.width * FlxCamera.defaultZoom;
            var _loc_3:* = FlxG.height * FlxCamera.defaultZoom;
            _loc_1.moveTo(0, 0);
            _loc_1.beginFill(0, 0.5);
            _loc_1.lineTo(_loc_2, 0);
            _loc_1.lineTo(_loc_2, _loc_3);
            _loc_1.lineTo(0, _loc_3);
            _loc_1.lineTo(0, 0);
            _loc_1.endFill();
            var _loc_4:* = _loc_2 / 2;
            var _loc_5:* = _loc_3 / 2;
            var _loc_6:* = FlxU.min(_loc_4, _loc_5) / 3;
            _loc_1.moveTo(_loc_4 - _loc_6, _loc_5 - _loc_6);
            _loc_1.beginFill(16777215, 0.65);
            _loc_1.lineTo(_loc_4 + _loc_6, _loc_5);
            _loc_1.lineTo(_loc_4 - _loc_6, _loc_5 + _loc_6);
            _loc_1.lineTo(_loc_4 - _loc_6, _loc_5 - _loc_6);
            _loc_1.endFill();
            var _loc_7:* = new this.ImgLogo();
            new this.ImgLogo().scaleX = int(_loc_6 / 10);
            if (_loc_7.scaleX < 1)
            {
                _loc_7.scaleX = 1;
            }
            _loc_7.scaleY = _loc_7.scaleX;
            _loc_7.x = _loc_7.x - _loc_7.scaleX;
            _loc_7.alpha = 0.35;
            this._focus.addChild(_loc_7);
            addChild(this._focus);
            return;
        }// end function

    }
}
